#include "wingbot_can.h"

void can_set_baudrate(CAN_InitTypeDef* def, uint16_t baud)
{
    if (baud==1000) /* 1MBps */
        def->CAN_Prescaler = 6;
    else if (baud == 500) /* 500KBps */
        def->CAN_Prescaler = 12;
    else if (baud == 250) /* 250KBps */
        def->CAN_Prescaler = 24;
    else if (baud == 125) /* 125KBps */
        def->CAN_Prescaler = 48;
    else if (baud == 100) /* 100KBps */
        def->CAN_Prescaler = 60;
    else if (baud == 50) /* 50KBps */
        def->CAN_Prescaler = 120;
    else if (baud == 20) /* 20KBps */
        def->CAN_Prescaler = 300;
    else if (baud == 10) /* 10KBps */
        def->CAN_Prescaler = 600;
}

/**
* @brief CAN初始化
* @param mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
* Can的波特率 = APB1总线频率(36M)/BRP分频器(CAN_Prescaler)/(SJWtq + tBS1 + tBS2)
*/

u8 can_mode_init(u8 mode, u16 baud)
{  
    GPIO_InitTypeDef       GPIO_InitStructure; 
    CAN_InitTypeDef        CAN_InitStructure;
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    
#if defined CAN1_RX0_INT_ENABLE 
    NVIC_InitTypeDef  NVIC_InitStructure;
#endif
    //使能相关时钟
    GPIO_PortClock(GPIOA, true);//使能PORTA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟
    
    //初始化GPIO
    GPIO_PinConfigure(RTE_CAN1_RX_PORT, RTE_CAN1_RX_BIT, GPIO_IN_PULL_UP, GPIO_MODE_INPUT);
    GPIO_PinConfigure(RTE_CAN1_TX_PORT, RTE_CAN1_TX_BIT, GPIO_AF_PUSHPULL, GPIO_MODE_OUT50MHZ);
      
    //CAN单元设置
    CAN_StructInit(&CAN_InitStructure);
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
    CAN_InitStructure.CAN_NART = ENABLE;
    CAN_InitStructure.CAN_Mode = mode;
    can_set_baudrate(&CAN_InitStructure, baud);
    CAN_Init(CAN1, &CAN_InitStructure);     // 初始化CAN1 

    //配置过滤器
    CAN_FilterInitStructure.CAN_FilterNumber = 0;                         //过滤器0
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; 
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;      //32位 
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;                    //32位ID
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;                //32位MASK
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;  //过滤器0关联到FIFO0
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;                //激活过滤器0
    CAN_FilterInit(&CAN_FilterInitStructure);                             //滤波器初始化
        
#if defined CAN1_RX0_INT_ENABLE
    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);                       //FIFO0消息挂号中断允许.
    /* 由于PA11和PA12也是USB的引脚，所以非互联型且带CAN控制器的微控制器的库文件在起名字时用了USB_LP_CAN1_RX0_IRQn。*/
    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
#endif

    return 0;
}

//can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)    
//len:数据长度(最大为8)                     
//msg:数据指针,最大为8个字节.
//返回值:0,成功;
//         其他,失败;
u8 can_send()
{    
    u8 mbox;
    uint32_t can_state = 0;
    u16 i=0;
    CanTxMsg TxMessage;
    TxMessage.StdId = 0x14;              // 标准标识符为0
    TxMessage.ExtId = 0x02;              // 设置扩展标示符（29位）
    TxMessage.IDE = CAN_ID_STD;          // 使用扩展标识符
    TxMessage.RTR = CAN_RTR_DATA;
    TxMessage.DLC = 8;
    for(i=0;i<8;i++)
        TxMessage.Data[i] = 0x30+i;
    mbox= CAN_Transmit(CAN1, &TxMessage);
    i=0; 
    do
    {
      can_state = CAN_TransmitStatus(CAN1, mbox);
      i++;    //等待发送结束
    }while((can_state!=CAN_TxStatus_Ok) && (i<0xFFF) );

    if(i>=0xFFF)return 1;
    return 0;

}

/* EOF */
